package cvut.fit.dpo.arithmetic;

import java.util.Iterator;
import java.util.LinkedList;

import cvut.fit.dpo.arithmetic.elements.CloseBracketOperation;
import cvut.fit.dpo.arithmetic.elements.ExpressionElement;
import cvut.fit.dpo.arithmetic.elements.OpenBracketOperation;
import cvut.fit.dpo.arithmetic.iterator.AbstractIterator;

/**
 * Represents the Binary operations like + - etc.
 * 
 * @author Jan Kurš
 * 
 */
public abstract class BinaryOperator extends ArithmeticExpression {
	final private ArithmeticExpression firstOperand;
	final private ArithmeticExpression secondOperand;

	public BinaryOperator(final ArithmeticExpression firstOperand,final ArithmeticExpression secondOperand) {
		this.firstOperand = firstOperand;
		this.secondOperand = secondOperand;
	}

	public ArithmeticExpression getFirstOperand() {
		return firstOperand;
	}

	public ArithmeticExpression getSecondOperand() {
		return secondOperand;
	}
	
	@Override
	public Iterator<ExpressionElement> getInOrderIterator() {
		return new AbstractIterator() {
			
			@Override
			protected Iterator<ExpressionElement> createIterator() {
				final LinkedList<ExpressionElement> list = new LinkedList<ExpressionElement>();
				list.add(new OpenBracketOperation());
				final Iterator<ExpressionElement> firstI = firstOperand.getInOrderIterator();
				while (firstI.hasNext()) {
					list.add(firstI.next());	
				}
				list.add(getRepresentationInExpresionModel());
				final Iterator<ExpressionElement> secondI = secondOperand.getInOrderIterator();
				while (secondI.hasNext()) {
					list.add(secondI.next());
				}
				list.add(new CloseBracketOperation());
				return list.iterator();
			}
			
		};
	}
	
	@Override
	public Iterator<ExpressionElement> getPostOrderIterator() {
		return new AbstractIterator() {
			
			@Override
			protected Iterator<ExpressionElement> createIterator() {
				final LinkedList<ExpressionElement> list = new LinkedList<ExpressionElement>();
				final Iterator<ExpressionElement> firstI = firstOperand.getPostOrderIterator();
				while (firstI.hasNext()) {
					list.add(firstI.next());	
				}
				final Iterator<ExpressionElement> secondI = secondOperand.getPostOrderIterator();
				while (secondI.hasNext()) {
					list.add(secondI.next());
				}
				list.add(getRepresentationInExpresionModel());
				return list.iterator();
			}
			
		};
	}
}
